<template>
  <div class="data-setting-container">
    <el-form v-if="sceneStore.selLayer" label-position="top">
      <el-form-item label="数据源类型">
        <el-select
          v-model="sceneStore.selLayer.effect.dataType"
          @change="handleDataSourceTypeChange"
          popper-class="dark-select-popper"
        >
          <el-option :value="'1'" label="静态数据"></el-option>
          <el-option :value="'2'" label="动态数据"></el-option>
          <el-option :value="'3'" label="物联网设备"></el-option>
        </el-select>
        <!-- <el-radio-group
                v-model="sceneStore.selLayer.effect.dataType"
                @change="handleDataSourceTypeChange"
              >
                <el-radio :label="'1'">静态数据</el-radio>
                <el-radio :label="'2'">动态数据</el-radio>
                <el-radio :label="'3'">物联网设备</el-radio>
              </el-radio-group> -->
      </el-form-item>
      <template v-if="sceneStore.selLayer.effect.dataType === '3'">
        <el-form-item label="设备">
          <el-select
            popper-class="dark-select-popper"
            v-model="sceneStore.selLayer.effect.deviceCode"
            v-loading="deviceListLoading"
            @change="handleDeviceChange"
          >
            <el-option
              v-for="item in deviceListData"
              :key="item.deviceCode"
              :value="item.deviceCode"
              :label="item.deviceName"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="模块">
          <el-select
            popper-class="dark-select-popper"
            v-model="sceneStore.selLayer.effect.moduleName"
            v-loading="moduleListLoading"
          >
            <el-option
              v-for="item in moduleList"
              :key="item.propName"
              :value="item.propName"
              :label="item.propName"
            ></el-option>
          </el-select>
        </el-form-item>
      </template>
      <template v-else>
        <el-form-item>
          <el-button type="primary" @click="setRequest">配置</el-button>
        </el-form-item>
      </template>
    </el-form>
    <div class="basic-data-wrap" v-if="sceneStore.selLayer">
      <el-form class="custom-form" @submit.native.prevent>
        <el-form-item label="定时刷新">
          <el-switch
            active-text="开"
            inline-prompt
            inactive-text="关"
            v-model="sceneStore.selLayer.effect.request.isRefrush"
            @change="setRefrushTime"
          />
        </el-form-item>
        <el-form-item label="刷新间隔">
          <div class="refrush-wrap">
            <el-input
              style="width: 200px"
              v-model="sceneStore.selLayer.effect.request.refrush"
              :disabled="!sceneStore.selLayer.effect.request.isRefrush"
            />
            <span>秒</span>
            <el-button type="primary" @click="setRefrushTime">调试</el-button>
          </div>
        </el-form-item>
      </el-form>
      <div class="request-data-wrap" v-if="requestSettingVisible">
        <el-form label-position="top">
          <el-form-item label="请求方法">
            <el-select
              popper-class="dark-select-popper"
              v-model="requestData.method"
              placeholder=""
            >
              <el-option label="GET" value="GET" />
              <el-option label="POST" value="POST" />
            </el-select>
          </el-form-item>
          <el-form-item label="请求URL">
            <el-input v-model="requestData.url" />
            <div class="tip">
              提示:https://wdt.51aes.com/source/ mode/action/{params1}?page={page}
            </div>
          </el-form-item>
          <el-form-item label="Ticket（请求凭据）">
            <el-input v-model="requestData.ticket" />
          </el-form-item>
          <el-form-item label="Post 请求参数" v-if="requestData.method === 'POST'">
            <el-input v-model="requestData.data" type="textarea" :autosize="{ minRows: 6 }" />
          </el-form-item>
          <el-form-item>
            <div class="footer">
              <el-button @click="requestSettingVisible = false">取消</el-button>
              <el-button type="primary" @click="saveRequest">保存</el-button>
            </div>
          </el-form-item>
        </el-form>
      </div>
    </div>
    <!-- 字段映射 -->
    <div v-if="fieldData.length" class="data-table">
      <div class="tr-th">
        <div>数据字段</div>
        <div>映射</div>
        <div>说明</div>
        <div>校验状态</div>
      </div>
      <div v-for="(item, index) in fieldData" :key="index" class="tr-td">
        <div>{{ item.code }}</div>
        <div>
          <el-select
            popper-class="dark-select-popper"
            v-model="item.mapping"
            placeholder="请选择"
            @change="selectchange"
          >
            <el-option
              v-for="option in mapOptions"
              :disabled="option.disabled"
              :key="option.value"
              :label="option.label"
              :value="option.value"
            />
          </el-select>
        </div>
        <div :title="item.description">{{ item.description }}</div>
        <div>
          <span class="img">
            <img v-if="item.check" src="@/assets/png/checkmark.png" alt="" />
            <img v-else src="@/assets/png/wrong.png" alt="" />
          </span>
        </div>
      </div>
    </div>
    <!-- 响应结果 -->
    <div
      class="response-wrap"
      v-if="sceneStore.selLayer && sceneStore.selLayer.effect.requestData.length"
    >
      <div class="title">响应结果</div>
      <div class="table-container">
        <table class="dark-table">
          <thead>
            <tr>
              <th v-for="(col, idx) in columns" :key="idx">{{ col.label }}</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(row, index) in tableData" :key="index">
              <td v-for="(col, idx) in columns" :key="idx">{{ row[col.prop] }}</td>
            </tr>
          </tbody>
        </table>
      </div>
      <!-- <div class="grid-wrap">
                    <div
                      class="grid-item"
                      v-for="list in sceneStore.selLayer.effect.requestData"
                      :key="list.label"
                    >
                      <div class="grid-item-label">{{ list.label }}</div>
                      <div class="grid-item-content">{{ list.value }}</div>
                    </div>
                  </div> -->
    </div>
  </div>
</template>

<script setup lang="ts">
import { useSceneStore } from '@/store/scene';
import { useRequest } from '@jl/common/composable';
import { IDeviceInfo, IModuleGetParam, IModuleInfo } from '@/api/iot/types';
import { getDeviceList, getModuleList } from '@/api/iot';
import { messageUtil } from '@jl/element-plus/utils';
import { isJSON } from '@/utils';
import { addlayerRequestIns, addParticle, layerRequestInsMap } from '@/service/effect';

defineOptions({
  name: 'LayerDataSetting',
});

const sceneStore = useSceneStore();
const requestSettingVisible = ref<boolean>(false);
const fieldData = ref<any>([]);
const columns = ref<any>([]);
const tableData = ref<any>([]);
const requestData = ref<any>({});

const {
  run: getDeviceListRun,
  data: deviceList,
  loading: deviceListLoading,
} = useRequest<API.Base.ResponsePage2<IDeviceInfo>, API.Base.RequestPageParam, any>(getDeviceList, {
  total: 0,
  rows: [],
});

const {
  run: getModuleListRun,
  data: moduleList,
  loading: moduleListLoading,
} = useRequest<IModuleInfo[], any, IModuleGetParam>(getModuleList, []);

const deviceListData = computed(() => {
  // const cdz = sceneStore.selLayer.code.indexOf('充电桩') > -1; // 类型是否为充电桩
  // return deviceList.value.rows.filter((v) => v.deviceName.indexOf(cdz ? '充电桩' : '光伏') > -1);
  return deviceList.value.rows;
});

// 获取options选项
const mapOptions = computed(() => {
  if (!sceneStore.selLayer) return [];
  return sceneStore.selLayer.effect.requestData.map((item: any) => {
    return {
      label: item.label,
      value: item.label,
      disabled: false,
    };
  });
});

function setRequest() {
  requestSettingVisible.value = true;
}

function saveRequest() {
  if (!requestData.value.url) {
    messageUtil.warning('请填写url');
    return;
  }
  if (!requestData.value.ticket) {
    messageUtil.warning('请填写ticket');
    return;
  }
  if (requestData.value.method === 'POST') {
    if (!requestData.value.data) {
      messageUtil.warning('请输入请求参数');
      return;
    }
    if (!isJSON(requestData.value.data)) {
      messageUtil.warning('请求参数必须为JSON字符串');
      return;
    }
  }
  if (!sceneStore.selLayer) return;
  sceneStore.selLayer.effect.request.method = requestData.value.method;
  sceneStore.selLayer.effect.request.url = requestData.value.url;
  sceneStore.selLayer.effect.request.ticket = requestData.value.ticket;
  sceneStore.selLayer.effect.request.data = requestData.value.data;
  addlayerRequestIns(sceneStore.selLayer);
  requestSettingVisible.value = false;
}

function setRefrushTime() {
  if (isNaN(sceneStore.selLayer.effect.request.refrush)) {
    messageUtil.warning('请输入数字');
    sceneStore.selLayer.effect.request.refrush = 0;
    return;
  }
  const ins: any = layerRequestInsMap.get(sceneStore.selLayer.layerName);
  if (!ins) {
    addlayerRequestIns(sceneStore.selLayer);
    return;
  }
  ins.refrush(sceneStore.selLayer.effect.request.refrush);
}

// 选择下拉后逻辑
const selectchange = () => {
  // 判断重复选择
  const sameMap: any = {};
  let repeatTipState = false;
  let residueTipState = false;
  for (const item of fieldData.value) {
    if (!item.mapping && !residueTipState) {
      messageUtil.warning('请选择剩余映射');
      residueTipState = true;
      continue;
    }
    item.check = true;
    if (sameMap[item.mapping]) {
      sameMap[item.mapping]++;
    } else {
      sameMap[item.mapping] = 1;
    }
  }
  fieldData.value.forEach((item: any) => {
    if (!item.mapping) {
      item.check = false;
    } else {
      item.check = true;
      if (item.mapping && sameMap[item.mapping] > 1) {
        repeatTipState = true;
        item.check = false;
      }
    }
  });
  if (repeatTipState) {
    messageUtil.warning('字段映射存在重复，请更改');
    return;
  }
  const dataMapping: any = {};
  fieldData.value.forEach((item: any) => {
    dataMapping[item.code] = item.mapping;
  });
  sceneStore.selLayer!.effect.dataMapping = dataMapping;
};

function handleDataSourceTypeChange() {
  if (!sceneStore.selLayer) return;
  if (sceneStore.selLayer.type !== 'div') {
    return;
  }
  requestSettingVisible.value = false;
  resetFields();
  sceneStore.selLayer.effect.deviceCode = '';
  sceneStore.selLayer.effect.moduleName = '';
  if (sceneStore.selLayer.effect.dataType !== '3') {
    return;
  }
  getDeviceListRun({
    data: {
      current: 1,
      pageSize: 1000,
    },
  });
}

const handleDeviceChange = async (deviceCode: string) => {
  if (!sceneStore.selLayer) return;
  if (sceneStore.selLayer!.type !== 'div') {
    return;
  }
  resetFields();
  sceneStore.selLayer.effect.moduleName = '';
  const item = deviceList.value.rows.find((o) => o.deviceCode === deviceCode)!;
  const { productCode } = item;
  await getModuleListRun({
    params: {
      deviceCode,
      productCode,
      type: 'PROP',
    },
  });
  const url = `/iot-api/device/runtime?deviceCode=${deviceCode}&productCode=${productCode}&type=PROP`;
  sceneStore.selLayer.effect.request.method = 'GET';
  sceneStore.selLayer.effect.request.url = url;
  addlayerRequestIns(sceneStore.selLayer);
};

function resetFields() {
  if (!sceneStore.selLayer) {
    return;
  }
  tableData.value = [];
  columns.value = [];
  sceneStore.selLayer.effect.requestData = [];
  sceneStore.selLayer.effect.dataMapping = {};
  fieldData.value.forEach((item: any) => {
    item.mapping = '';
    item.check = false;
  });
}

watch(
  () => sceneStore.selLayer?.code,
  async () => {
    if (sceneStore.selLayer && sceneStore.selLayer.effect) {
      requestData.value = sceneStore.selLayer.effect.request;
      fieldData.value = sceneStore.selLayer.effect.fieldDef.map((item: any) => {
        const param = {
          code: item.value,
          mapping: sceneStore.selLayer!.effect.dataMapping[item.value] || '',
          description: item.label,
          check: !!sceneStore.selLayer!.effect.dataMapping[item.value],
        };
        return param;
      });
      await getDeviceListRun({
        data: {
          current: 1,
          pageSize: 1000,
        },
      });
      if (sceneStore.selLayer.effect!.deviceCode) {
        const item = deviceList.value.rows.find(
          (o) => o.deviceCode === sceneStore.selLayer.effect.deviceCode
        )!;
        if (!item) return;
        const { productCode } = item;
        await getModuleListRun({
          params: {
            deviceCode: sceneStore.selLayer.effect.deviceCode,
            productCode,
            type: 'PROP',
          },
        });
      }
    }
  },
  {
    immediate: true,
  }
);

watch(
  () => sceneStore.selLayer?.effect?.requestData,
  () => {
    if (sceneStore.selLayer?.effect?.requestData.length) {
      columns.value = [];
      const obj: any = {};
      columns.value.push({
        prop: '序号',
        label: '序号',
      });
      for (const item of sceneStore.selLayer.effect.requestData) {
        columns.value.push({
          prop: item.label,
          label: item.label,
        });
        obj[item.label] = item.value;
      }
      obj['序号'] = 1;
      tableData.value = [obj];
    }
  },
  {
    deep: true,
    immediate: true,
  }
);
</script>

<style lang="less" scoped>
.data-setting-container {
  padding: 0 20px;
  .basic-data-wrap {
    position: relative;
    .custom-form {
      .el-form-item {
        display: block;
      }
    }

    .request-data-wrap {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      // height: 380px;
      background: #0a0b0d;
      z-index: 10;
      padding: 10px;
      border-radius: 8px;
      border: 1px solid rgba(151, 151, 151, 0.3);

      .tip {
        opacity: 0.45;
        height: 36px;
        line-height: 18px;
        margin-top: 8px;
      }

      .footer {
        width: 100%;
        display: flex;
        justify-content: center;
        margin-top: 5px;
      }
    }
    .refrush-wrap {
      width: 100%;
      display: flex;

      span {
        margin-left: 10px;
        margin-right: 10px;
      }
    }
  }
  .response-wrap {
    margin-top: 20px;
    .grid-wrap {
      border-top: 1px solid #fff;
      border-left: 1px solid #fff;
      margin-top: 10px;
      .grid-item {
        display: flex;
        align-items: center;

        &-label,
        &-content {
          height: 28px;
          line-height: 28px;
          border-right: 1px solid #fff;
          border-bottom: 1px solid #fff;
          padding: 0 2px;
        }
        &-label {
          flex: 0 0 100px;
        }
        &-content {
          flex: 1;
        }
      }
    }
  }
  .data-table {
    margin-top: 10px;
    overflow-x: auto;

    /* 自定义横向滚动条样式 */
    /* 滚动条整体 */
    &::-webkit-scrollbar {
      height: 3px;
    }

    /* 滚动条轨道 */
    &::-webkit-scrollbar-track {
      background: #2f333b;
    }

    /* 滚动条滑块 */
    &::-webkit-scrollbar-thumb {
      background: #0560fd;
      opacity: 0.54;
    }

    /* 滚动条滑块悬停状态 */
    &::-webkit-scrollbar-thumb:hover {
      background: #0560fd;
      opacity: 0.6;
    }

    .tr-th {
      display: grid;
      grid-template-columns: 20% 35% 20% 20%;
      font-size: 12px;
      // text-align: center;
      height: 35px;
      line-height: 35px;
      grid-column-gap: 20px;
      grid-auto-flow: column;
    }
    .tr-td {
      display: grid;
      grid-template-columns: 20% 35% 20% 20%;
      font-size: 12px;
      // text-align: center;
      height: 30px;
      line-height: 30px;
      margin-bottom: 10px;
      grid-column-gap: 20px;
      grid-auto-flow: column;
      .el-select {
        height: 30px;
        line-height: 30px;
        :deep(.el-input) {
          height: 30px;
          line-height: 30px;
          .el-input__wrapper {
            padding: 1px 10px;
            background: #2c2c2c;
            border: none;
            box-shadow: none;
            color: #fff;
            .el-input__inner {
              color: #fff;
              font-size: 12px;
              &::placeholder {
                font-size: 12px;
              }
            }
          }
          &.is-focus {
            .el-input__wrapper {
              box-shadow: none !important;
            }
          }
        }
      }
      .img {
        display: block;
        width: 20px;
        height: 20px;
        // margin: 0 auto;
        margin-top: 5px;
        img {
          width: 100%;
          height: 100%;
        }
      }
      & > div {
        &:nth-child(3) {
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
      }
    }
    &-three {
      .tr-th {
        grid-template-columns: 30% 50% 20%;
      }
      .tr-td {
        grid-template-columns: 30% 50% 20%;
        :deep(.el-input) {
          height: 30px;
          line-height: 30px;
          .el-input__wrapper {
            padding: 1px 10px;
            background: #2c2c2c;
            border: none;
            box-shadow: none;
            color: #fff;
            .el-input__inner {
              color: #fff;
              font-size: 12px;
              &::placeholder {
                font-size: 12px;
              }
            }
          }
          &.is-focus {
            .el-input__wrapper {
              box-shadow: none !important;
            }
          }
        }
      }
    }
  }
}
</style>
